using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using AppScan;
using AppScan.Scan.Results;
using TDAPIOLELib;
using System.Runtime.InteropServices;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

namespace AppScan.DefectLogger
{
	partial class LogDefectForm
	{
		private void LogBtn_Click(object sender, EventArgs e)
		{
			// Make sure we have a the minimal data
			if (string.IsNullOrEmpty(SubjectTB.Text) || string.IsNullOrEmpty(DescriptionTB.Text))
			{
				MessageBox.Show("The subject & Description must be filled");
				return;
			}

			IDefectTrackingSystem defectSystem;
			try
			{
				defectSystem = _extension.DefectTrackingSystem;

				defectSystem.Login(_extension.Config.ServerUrl, UserNameTB.Text, PasswordTB.Text, _extension.Config.DomainName, _extension.Config.ProjectName);
			}
			catch (Exception)
			{
				MessageBox.Show("Login failed.");
				return;
			}


			try
			{
				TDConnection connection = defectSystem.NativeConnection as TDConnection;
	
				IBugFactory bugFactory = connection.BugFactory as IBugFactory;

				// Create a map from field name to actual TD Field
				Dictionary<string, TDField> nameToTDField = new Dictionary<string, TDField>();
				List TDFields = bugFactory.Fields;
				for (int i = 1; i <= TDFields.Count; i++)
				{
					TDField tdField = TDFields[i] as TDField;
					nameToTDField[tdField.Name] = tdField;
				}

				// Make sure all required fields are filled
				foreach (Control dataControl in _dataControls)
				{
					// Get the field
					Field field = dataControl.Tag as Field;
					System.Diagnostics.Debug.Assert(field != null);

					// Make sure we have a value
					string val = GetValueFromDataControl(dataControl);

					// Check if it's required
					if (field.Required)
					{
						if (string.IsNullOrEmpty(val))
						{
							MessageBox.Show("Required field " + field.DisplayName + " isn't filled");
							return;
						}
					}

					// Make sure the entered value is legal
					TDField tdField = nameToTDField[field.Name];
					try
					{
						tdField.IsValidValue(val, tdField);
					}
					catch (COMException ex)
					{
						MessageBox.Show("Value of field " + field.DisplayName + " is invalid." + Environment.NewLine +
										Environment.NewLine +
										"Details: " + ex);
						return;
					}
				}

				// We got here safe - we should be able to create and log a bug
				IBug bug = bugFactory.AddItem(SubjectTB.Text) as IBug;
				// Fill all the fields
				foreach (Control dataControl in _dataControls)
				{
					// Get the field
					Field field = dataControl.Tag as Field;
					System.Diagnostics.Debug.Assert(field != null);

					// Make sure we have a value
					string val = GetValueFromDataControl(dataControl);
					bug[field.Name] = val;
				}

				// If we have a description field, use it
				if (nameToTDField.ContainsKey(descFieldName))
					bug[descFieldName] = DescriptionTB.Text;
				bug.DetectedBy = UserNameTB.Text;
				bug.Summary = SubjectTB.Text;
				bug.Post();

				// Add the attachements
				IAttachmentFactory attachFactory = bug.Attachments as IAttachmentFactory;
				foreach (ListViewItem fileItem in filesListView.Items)
				{
					FileInfo fileInfo = new FileInfo((string)fileItem.Tag);
					object[] arr = new object[3];
					arr[0] = fileInfo.FullName;
					arr[1] = tagTDAPI_ATTACH.TDATT_COPY;
					arr[2] = fileInfo.Name;
					IAttachment attachment = attachFactory.AddItem(arr) as IAttachment;

					attachment.Post();
				}
				bug.Post();

				// Save the password
				_extension.Config.Password = PasswordTB.Text;

				// Notify the bug was logged
				MessageBox.Show("Successfully logged as defect " + bug.ID.ToString());
				Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Failed to log defect: " + ex.Message);
				return;
			}
		}

		private void DoOnLoadUpdates()
		{
			return;
		}
	}
}
